package com.lecyon.farm.service.impl;

import com.google.common.collect.Lists;
import com.lecyon.farm.base.RestResponse;
import com.lecyon.farm.common.constant.CommonConstant;
import com.lecyon.farm.common.constant.FarmSysConstant;
import com.lecyon.farm.entity.elasticsearch.SimpleGps;
import com.lecyon.farm.mapper.SimpleGpsRepository;
import com.lecyon.farm.service.ISimpleGpsService;
import com.lecyon.farm.util.StringHelper;
import com.lecyon.farm.util.ValidateUtils;
import com.lecyon.farm.vo.query.QuerySimpleGpsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author Yao Zheng
 * @Date 2020/3/23 18:23
 */
@Service
@Slf4j
public class SimpleGpsServiceImpl implements ISimpleGpsService {

    private SimpleGpsRepository simpleGpsRepository;

    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(CommonConstant.DATE_TIME_FORMAT_PATTERN);

    /**
     * 保存位置信息
     *
     * @param entity 设备状态明细
     * @return MongoEquipmentStatusDetail
     */
    @Override
    public RestResponse<SimpleGps> save(SimpleGps entity) {
        return null;
    }

    /**
     * 根据条件查询位置信息
     *
     * @param queryVo 查询条件
     * @return 位置信息
     */
    @Override
    public List<SimpleGps> getList(QuerySimpleGpsVo queryVo) {
        List<SimpleGps> result = Lists.newArrayList();
        String beginTime = queryVo.getBeginTime();
        String endTime = queryVo.getEndTime();
        String carId = queryVo.getCarId();
        String commandId = queryVo.getCommandID();
        List<SimpleGps> resultList;
        if (StringHelper.isNotEmpty(beginTime) && StringHelper.isNotEmpty(endTime)) {
            resultList = simpleGpsRepository.findByCarIdAndCommandIDAndTimeBetween(queryVo.getCarId(), queryVo.getCommandID(), beginTime, endTime);
            LocalDateTime begin = LocalDateTime.parse(beginTime, dateTimeFormatter);
            LocalDateTime end = LocalDateTime.parse(endTime, dateTimeFormatter);
            LocalDateTime recordTime;
            if (CollectionUtils.isNotEmpty(resultList)) {
                for (SimpleGps entity : resultList) {
                    if (StringHelper.isEmpty(entity.getCarId()) || !carId.equals(entity.getCarId())) {
                        continue;
                    }
                    if (StringHelper.isEmpty(entity.getCommandID()) || !commandId.equals(entity.getCommandID())) {
                        continue;
                    }
                    if (StringHelper.isNotEmpty(entity.getTime())) {
                        recordTime = LocalDateTime.parse(entity.getTime(), dateTimeFormatter);
                        if (recordTime.isBefore(begin) || recordTime.isAfter(end)) {
                            continue;
                        }
                    }
                    result.add(entity);
                }
            }
        } else {
            resultList = simpleGpsRepository.findByCarIdAndCommandID(queryVo.getCarId(), queryVo.getCommandID());
            BigDecimal lat, lon;
            Double gpsInvalidData = 0.0;
            String invalidCharacter = "0";
            if (CollectionUtils.isNotEmpty(resultList)) {
                String lonStr, latStr;
                for (SimpleGps entity : resultList) {
                    if (StringHelper.isEmpty(entity.getCarId()) || !carId.equals(entity.getCarId())) {
                        continue;
                    }
                    if (StringHelper.isEmpty(entity.getCommandID()) || !commandId.equals(entity.getCommandID())) {
                        continue;
                    }
                    if (StringHelper.isEmpty(entity.getGpsLat()) || StringHelper.isEmpty(entity.getGpsLon())) {
                        continue;
                    }
                    lonStr = entity.getGpsLon();
                    latStr = entity.getGpsLat();
                    if ("0".equals(lonStr) || "0".equals(latStr)) {
                        continue;
                    }
                    // 以0开头 以0结尾，一般都是全零字符串
                    if (lonStr.startsWith(invalidCharacter) && lonStr.endsWith(invalidCharacter)) {
                        continue;
                    }
                    if (latStr.startsWith(invalidCharacter) && latStr.endsWith(invalidCharacter)) {
                        continue;
                    }
                    lat = new BigDecimal(latStr);
                    lon = new BigDecimal(lonStr);
                    if (FarmSysConstant.GPS_INVALID_DATA.equals(lat) || FarmSysConstant.GPS_INVALID_DATA.equals(lon)) {
                        continue;
                    }
                    if (gpsInvalidData == lat.doubleValue() || gpsInvalidData == lon.doubleValue()) {
                        continue;
                    }
                    result.add(entity);
                }
            }
        }
        return result;
    }

    /**
     * 根据条件查询设备最近一次的位置
     *
     * @param querySimpleGpsVo
     * @return
     */
    @Override
    public SimpleGps getLastLocation(QuerySimpleGpsVo querySimpleGpsVo) {
        SimpleGps result = null;
        if (ValidateUtils.isNotNullOrEmpty(querySimpleGpsVo) && ValidateUtils.isNotNullOrEmpty(querySimpleGpsVo.getLastQueryTime())) {
            LocalDateTime beginTime = querySimpleGpsVo.getLastQueryTime().plusMinutes(-FarmSysConstant.MACHINE_TRAILS_INTERVAL);
            LocalDateTime endTime = querySimpleGpsVo.getLastQueryTime();
            querySimpleGpsVo.setBeginTime(dateTimeFormatter.format(beginTime));
            querySimpleGpsVo.setEndTime(dateTimeFormatter.format(endTime));
        }
        List<SimpleGps> simpleGpsList = getList(querySimpleGpsVo);
        if (CollectionUtils.isNotEmpty(simpleGpsList)) {
            LocalDateTime recordTime, lastRecordTime = null;
            LocalDateTime lastQueryTime = querySimpleGpsVo.getLastQueryTime();
            String timeStr;
            for (SimpleGps simpleGps : simpleGpsList) {
                if (StringHelper.isNotEmpty(simpleGps.getTime())) {
                    timeStr = simpleGps.getTime();
                    recordTime = LocalDateTime.parse(timeStr, dateTimeFormatter);
                    if (ValidateUtils.isNotNullOrEmpty(lastQueryTime) && lastQueryTime.isBefore(recordTime)) {
                        log.info("recordTime = {} 被过滤", dateTimeFormatter.format(recordTime));
                        continue;
                    }
                    if (ValidateUtils.isNullOrEmpty(lastRecordTime) || lastRecordTime.isBefore(recordTime)) {
                        lastRecordTime = recordTime;
                        result = simpleGps;
                    }
                }
            }
        }
        return result;
    }

    /**
     * ----------------------------- 分割线 以下是setter方法，用于替换field上的@Autowired -----------------------------
     */
    @Autowired
    @Lazy
    public void setSimpleGpsRepository(SimpleGpsRepository simpleGpsRepository) {
        this.simpleGpsRepository = simpleGpsRepository;
    }
}
